package com.hefan.oms.service;

import com.alibaba.fastjson.JSON;
import com.cat.common.constant.RedisKeyConstant;
import com.cat.tiger.service.JedisService;
import com.cat.tiger.util.CollectionUtils;
import com.cat.tiger.util.GlobalConstants;
import com.google.common.collect.Lists;
import com.hefan.common.constant.InitUserConstants;
import com.hefan.common.exception.DataIllegalException;
import com.hefan.oms.algorithm.RedPacketAlgorithm;
import com.hefan.oms.algorithm.RedPacketImpl;
import com.hefan.oms.bean.*;
import com.hefan.oms.dao.OrderRedPacketDao;
import com.hefan.oms.dao.OrderRedPacketDetailDao;
import com.hefan.oms.dao.RedPacketDao;
import com.hefan.oms.dao.TradeLogDao;
import com.hefan.oms.itf.AccountService;
import com.hefan.oms.itf.CurrencyExchangeService;
import com.hefan.oms.itf.RedPacketService;
import com.hefan.user.bean.WebUser;
import com.hefan.user.itf.WebUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Created by hbchen on 2016/10/12.
 */
@Component("redPacketService")
public class RedPacketServiceImpl implements RedPacketService {

  @Resource
  private RedPacketDao redPacketDao;
  @Resource
  private OrderRedPacketDetailDao orderRedPacketDetailDao;
  @Resource
  private OrderRedPacketDao orderRedPacketDao;
  @Resource
  private JedisService jedisService;
  @Resource
  private TradeLogDao tradeLogDao;
  @Resource
  private WebUserService webUserService;
  @Resource
  private CurrencyExchangeService currencyExchangeService;
  @Resource
  private AccountService accountService;



  private Logger logger = LoggerFactory.getLogger(RedPacketServiceImpl.class);

  @Override
  public RedPacket selectRedPackInfo(int id) {
    return redPacketDao.selectRedPackInfo(id);
  }

  @Override
  public void updateRedPackOrderStatus(long orderId) throws Exception {
    redPacketDao.updateRedPackOrderStatus(orderId);
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public void updateRedPackDetail(long detailId, String userId) throws Exception {
    orderRedPacketDetailDao.updateRedPackDetail(detailId, userId);
  }

  @Override
  public int selectRedPackDetailCount(long orderId) {
    return orderRedPacketDetailDao.selectRedPackDetailCount(orderId);
  }

  @Override
  public void updateRedPackOrderStatus(String liveUuid) throws Exception{
    List<OrderRedPacket> list = orderRedPacketDao.selectUnFinishRedPackList(liveUuid);
    if (!CollectionUtils.isEmptyList(list)) {
      for (OrderRedPacket orderRedPacket : list) {
        String pkey = String.format(RedisKeyConstant.RED_PACKET_MONEY_KEY, new Object[] { orderRedPacket.getId() });
          jedisService.del(pkey);
      }
    }
    //将所有未领取红包，更新到平台账户
    Integer fanpiaoNum = redPacketDao.updateRedPack2Platform(liveUuid);
    logger.info("直播{}结束后剩余红包饭票数{}", liveUuid, fanpiaoNum);
    if (fanpiaoNum != null) {
      WebUser user = webUserService.getWebUserInfoByUserId(InitUserConstants.OFFICE_USER_ID);
      webUserService.incrWebUserBalance(user.getUserId(), fanpiaoNum);
      //查询饭票兑换人民币
      Double amount=currencyExchangeService.exchangeFanPiao2Object(fanpiaoNum);

      //记充值记录
      TradeLog tradeLog = new TradeLog();
      tradeLog.setOrderId(liveUuid);
      tradeLog.setNickName(user.getNickName());
      tradeLog.setUserId(user.getUserId());
      tradeLog.setRewardFanpiao(fanpiaoNum);
      tradeLog.setRewardFanpiaoAmount(BigDecimal.valueOf(amount));
      tradeLog.setIncomeAmount(new BigDecimal(fanpiaoNum));
      tradeLog.setRemark("直播间关闭--未抢红包金额增加到平台赠送账户");
      tradeLog.setAccountType(GlobalConstants.PAY_SOURCE_REDPACK);
      tradeLog.setAccountStatus("SUCESS");
      tradeLog.setPayStatus(3);
      tradeLog.setPayBeforeFanpiao(user.getBalance().intValue());
      tradeLog.setPayAfterFanpiao(user.getBalance().intValue() + fanpiaoNum);
      tradeLog.setPayNotifyDate(new Date());
      tradeLogDao.insertNewRecord(tradeLog);
      redPacketDao.updateRedPackOrderStatus(liveUuid);
    }
  }

  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public long pushRedPacket(RedPacketVo redPacketVo, WebUser webUser) throws Exception {

    //记红包订单order_packet
    OrderRedPacket orderRedPacket = new OrderRedPacket();
    orderRedPacket.setLiveUuid(redPacketVo.getLiveUuid());
    orderRedPacket.setUserId(redPacketVo.getUserId());
    orderRedPacket.setFanpiaoNum(redPacketVo.getFanpiaoNum());
    orderRedPacket.setPacketNum(redPacketVo.getPersonNum());
    long orderid = orderRedPacketDao.insertNewRecord(orderRedPacket);

    RedPacketAlgorithm redPacketAlgorithm = new RedPacketImpl();
    //红包算法
    double[] doubles = redPacketAlgorithm.decompose(redPacketVo.getFanpiaoNum(), redPacketVo.getPersonNum());

    List<OrderRedPacketDetail> list = Lists.newArrayList();
    for (int i = 0; i < orderRedPacket.getPacketNum(); i++) {
      OrderRedPacketDetail orderRedPacketDetail = new OrderRedPacketDetail();
      orderRedPacketDetail.setFanpiaoNum((int) doubles[i]);
      orderRedPacketDetail.setUserId("");
      orderRedPacketDetail.setOrderId(orderid);
      orderRedPacketDetail.setLiveUuid(redPacketVo.getLiveUuid());
      list.add(orderRedPacketDetail);
    }
    if (!list.isEmpty()) {//批量
      orderRedPacketDetailDao.batchInsertNewRecord(list);
    }
    //主播增加盒饭数
    int fanPiaoNum = Double.valueOf(redPacketVo.getPresentFanpiao()).intValue();
    //饭票兑换盒饭
    int hefanNum = currencyExchangeService.exchangeFanPiao2HeFan(fanPiaoNum, GlobalConstants.EX_RULE_FANPIAO_HEFAN);
    //记录主播获得盒饭数,
    webUserService.icrWebUserHefanTotal(redPacketVo.getZhuboId(), hefanNum);

    RebalanceVo rebalanceVo = new RebalanceVo();
    rebalanceVo.setToId(redPacketVo.getZhuboId());
    rebalanceVo.setLiveUuid(redPacketVo.getLiveUuid());
    rebalanceVo.setFromId(redPacketVo.getUserId());
    rebalanceVo.setPresentId(redPacketVo.getPresentId());
    rebalanceVo.setPresentName(redPacketVo.getPresentName());
    rebalanceVo.setPresentNum(1);
    rebalanceVo.setPrice(redPacketVo.getPresentFanpiao());
    rebalanceVo.setSource(GlobalConstants.SOURCE_TYPE_LIVE);
    rebalanceVo.setIsFalse(GlobalConstants.REAL_FANPIAO);
    rebalanceVo.setBeforeFanpiao(redPacketVo.getBeforeFanpiao());
    rebalanceVo.setExp(redPacketVo.getExp());
    accountService.dealAccountDetail(rebalanceVo, hefanNum, fanPiaoNum, webUser);
    //4.2017-02-07 add by 王超：扣费成功后更新主播排行榜：总榜和月榜
    /*try {
      webUserService.updateRankByRebalance(rebalanceVo.getFromId(), rebalanceVo.getToId(), hefanNum);
    } catch (Exception e) {
      logger.error("redis更新主播排行榜{}收入{}异常", rebalanceVo.getToId(), hefanNum, e);
    }*/
    /*
    // 给队列发消息，完成后续工作
    String onsEnv = DynamicProperties.getString("ons.env");
    com.hefan.common.ons.bean.Message message = new com.hefan.common.ons.bean.Message();
    message.setTag(onsEnv);
    message.put("rebalanceVo", JSONObject.toJSONString(rebalanceVo));
    message.setTopic(TopicRegistry.HEFANTV_OMS_LOG);
    logger.info("红包直播扣费记录账目{}", JSONObject.toJSONString(message));
    onsProducer.sendMsg(message);
*/

    return orderid;
  }

  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public void grapRedPacket(RedPackQiangVo redPackQiangVo) throws Exception {
    //查询中奖人
    WebUser user = webUserService.getWebUserInfoByUserId(redPackQiangVo.getUserId());
    if(user == null){
      logger.error("抢红包人不存在{}", JSON.toJSONString(redPackQiangVo));
      throw new DataIllegalException(String.format("抢红包人不存在%s",JSON.toJSONString(redPackQiangVo)));
    }
    //记充值记录
    TradeLog tradeLog = new TradeLog();
    //查询饭票兑换人民币
    Double amount=currencyExchangeService.exchangeFanPiao2Object(redPackQiangVo.getFanpiaoNum());
    tradeLog.setOrderId(String.valueOf(redPackQiangVo.getDetailId()));
    tradeLog.setNickName(user.getNickName());
    tradeLog.setUserId(redPackQiangVo.getUserId());
    tradeLog.setRewardFanpiao(redPackQiangVo.getFanpiaoNum());
    tradeLog.setRewardFanpiaoAmount(BigDecimal.valueOf(amount));
    tradeLog.setRemark("抢红包收入");
    tradeLog.setIncomeAmount(new BigDecimal(redPackQiangVo.getFanpiaoNum()));
    tradeLog.setAccountType(GlobalConstants.PAY_SOURCE_REDPACK);
    tradeLog.setAccountStatus("SUCESS");
    tradeLog.setPayBeforeFanpiao(user.getBalance().intValue());
    tradeLog.setPayAfterFanpiao(user.getBalance().intValue() + redPackQiangVo.getFanpiaoNum());
    tradeLog.setPayStatus(3);
    tradeLog.setPayNotifyDate(new Date());
    tradeLogDao.insertNewRecord(tradeLog);

    //更新红包明细表
    orderRedPacketDetailDao.updateRedPackDetail(redPackQiangVo.getDetailId(), redPackQiangVo.getUserId());

    //判断红包是否抢完了，更新状态`
    int count = orderRedPacketDetailDao.selectRedPackDetailCount(redPackQiangVo.getOrderId());
    if (count == 0) {
      redPacketDao.updateRedPackOrderStatus(redPackQiangVo.getOrderId());
    }
    //更新中奖人余额
    webUserService.incrWebUserBalance(redPackQiangVo.getUserId(),redPackQiangVo.getFanpiaoNum());
  }

  @Override
  public OrderRedPacket getOrderPacketbyId(long id) {
    return redPacketDao.getOrderPacketbyId(id);
  }

  @Override
  public boolean isGrabRedPack(long orderId, String userId) {
    return redPacketDao.isGrabRedPack(orderId, userId);
  }

}
